package com.wyz.note.project.auth.core.interceptor;

import com.wyz.note.project.auth.common.enums.ResultCode;
import com.wyz.note.project.auth.core.base.Result;
import com.wyz.note.project.auth.core.exception.TokenException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.Servlet;
import javax.servlet.ServletException;


/**
 * @Description: 自定义异常拦截器
 * @author: wei yz
 * @Date: 2022/1/21
 */
@RestControllerAdvice
public class ExceptionInterceptor {

    private static final Logger log = LoggerFactory.getLogger(ExceptionInterceptor.class);


    /**
     * @param e
     * @return
     * @Title: BadCredentialsException
     * @Description: 认证异常处理 密码错误
     */
    @ExceptionHandler(BadCredentialsException.class)
    public Result badCredentialsException(BadCredentialsException e) {
        return new Result()
                .setCode(ResultCode.UNAUTHORIZED)
                .setSuccess(false)
                .setMessage("用户名或密码错误");
    }

    /**
     * @param e
     * @return
     * @Title: UsernameNotFoundException
     * @Description: 认证异常处理 用戶名
     */
    @ExceptionHandler(UsernameNotFoundException.class)
    public Result usernameNotFoundException(UsernameNotFoundException e) {
        return new Result()
                .setCode(ResultCode.UNAUTHORIZED)
                .setSuccess(false)
                .setMessage("用户名或密码错误");
    }

    /**
     * @param e
     * @return
     * @Title: TokenException
     * @Description: 没有权限
     */
    @ExceptionHandler(AccessDeniedException.class)
    public Result servletException(AccessDeniedException e) {
        return new Result()
                .setCode(ResultCode.NOT_PERMISSION)
                .setData(null)
                .setSuccess(false)
                .setMessage(e.getMessage());
    }

    /**
     * @param e
     * @return
     * @Title: TokenException
     * @Description: token异常处理 用戶名
     */
    @ExceptionHandler(InternalAuthenticationServiceException.class)
    public Result servletException(TokenException e) {
        return new Result()
                .setCode(ResultCode.FAIL)
                .setSuccess(false)
                .setMessage("token失效或不存在");
    }

    /**
     * @param e
     * @return
     * @Title: TokenException
     * @Description: token异常处理 用戶名
     */
    @ExceptionHandler(InsufficientAuthenticationException.class)
    public Result insufficientAuthenticationException(InsufficientAuthenticationException e) {
        return new Result()
                .setCode(ResultCode.FAIL)
                .setSuccess(false)
                .setMessage("权限不足");
    }

    /**
     * @param e
     * @return
     * @Title: UsernameNotFoundException
     * @Description: 认证异常处理 用戶名
     */
    @ExceptionHandler(Exception.class)
    public Result exception(Exception e) {
        return new Result()
                .setCode(ResultCode.UNAUTHORIZED)
                .setSuccess(false)
                .setMessage(e.getMessage());
    }

    /**
     * @param e
     * @return
     * @Title: UsernameNotFoundException
     * @Description: 认证异常处理 用戶名
     */
    @ExceptionHandler(Throwable.class)
    public Result throwable(Throwable e) {
        log.info("==> 顶级父类Throwable：{}", e.getMessage());
        return new Result()
                .setCode(ResultCode.INTERNAL_SERVER_ERROR)
                .setSuccess(false)
                .setMessage(e.getMessage());
    }

}
